/**
 * @author Created by qiush on 2017-07-03.
 */

import * as React from 'react';

import {IDesign} from '../../types/IDesign';
import {DesignNamesState} from '../../store/designNamesReducer';

import TabTitle from './TabTitle';

import './TabTitlePane.css';

export interface ITabTitleOptions {
  tabOverlapDistance?: number;
  minWidth?: number;
  maxWidth?: number;
  tabPadding?: number;
}

export interface TabTitlePaneProps {
  designs: IDesign[];
  designNames: DesignNamesState;
  activeDesign: IDesign;
  options?: ITabTitleOptions;
}

class TabTitlePane extends React.Component<TabTitlePaneProps, undefined> {

  private options: ITabTitleOptions = {
    tabOverlapDistance: 14,
    minWidth: 45,
    maxWidth: 243,
    tabPadding: 24
  };

  constructor(props) {
    super(props);

    this.options = {...this.options, ...props.options};
  }

  render() {
    const designs: IDesign[] = this.props.designs;
    const generatedCss: string = this.generateStyle();
    const tabStyles: React.CSSProperties[] = this.generateTabStyles();
    const tabBottomBarStyle: React.CSSProperties = {
      zIndex: designs.length + 1
    };
    return (
      <div className="Tab-titles">
        <style>{generatedCss}</style>
        <div className="Tab-titles-content">
          {designs.map((design: IDesign, index: number) => this.renderTabTitle(design, tabStyles[index]))}
        </div>
        <div className="Tab-titles-bottom-bar" style={tabBottomBarStyle}/>
      </div>
    );
  }

  private renderTabTitle(design: IDesign, tabStyle: React.CSSProperties): JSX.Element {
    const {designNames, activeDesign} = this.props;
    const props = {
      key: design.id,
      design,
      designName: designNames[design.id],
      isActive: design.id === activeDesign.id,
      tabStyle
    };
    return (
      <TabTitle {...props} />
    );
  }

  private calcTabWidth(): number {
    const contentWidth: number = window.innerWidth - this.options.tabOverlapDistance - this.options.tabPadding;
    const width: number = (contentWidth / this.props.designs.length) + this.options.tabOverlapDistance;
    return Math.max(this.options.minWidth, Math.min(this.options.maxWidth, width));
  }

  private calcTabEffectiveWidth(): number {
    return this.calcTabWidth() - this.options.tabOverlapDistance;
  }

  private calcTabPositions(): number[] {
    const tabEffectiveWidth: number = this.calcTabEffectiveWidth();
    return this.props.designs.map((_: IDesign, index: number): number => {
      return index * tabEffectiveWidth;
    });
  }

  private generateStyle(): string {
    const tabPositions: number[] = this.calcTabPositions();
    const rules: string[] = tabPositions.map((left: number, index: number): string => {
      return `.Tab-titles .Tab-title:nth-child(${index + 1}) {  transform: translate3d(${left}px, 0, 0); }`;
    });
    return rules.join('');
  }

  private generateTabStyles(): React.CSSProperties[] {
    const tabWidth = this.calcTabWidth();

    const {designs, activeDesign} = this.props;
    const designsLength = designs.length;
    return designs.map((design: IDesign, index: number): React.CSSProperties => {
      if (design.id === activeDesign.id) {
        return {
          width: tabWidth,
          zIndex: designsLength + 2
        };
      } else {
        return {
          width: tabWidth,
          zIndex: designsLength - index
        };
      }
    });
  }
}

export default TabTitlePane;
